package com.qboot.system.service.impl;

import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qboot.common.consts.RedisConst;
import com.qboot.common.consts.MsgConst;
import com.qboot.common.entity.Result;
import com.qboot.common.properties.QbootProperties;
import com.qboot.common.utils.AssertUtils;
import com.qboot.common.utils.RedisUtils;
import com.qboot.common.utils.SaTokenUtils;
import com.qboot.system.entity.SysPermission;
import com.qboot.system.entity.SysUser;
import com.qboot.system.service.LoginService;
import com.qboot.system.service.SysPermissionService;
import com.qboot.system.service.SysUserService;
import com.qboot.system.utils.MenuUtils;
import com.qboot.system.vo.LoginBodyVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 登录 接口实现类
 *
 * @author Tellsea
 * @date 2022/11/25
 */
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class LoginServiceImpl implements LoginService {

    private final QbootProperties qbootProperties;
    private final SysUserService userService;
    private final SysPermissionService permissionService;

    @Override
    public Result login(LoginBodyVo entity) {
        AssertUtils.isEmpty(entity.getUsername(), "用户名不能为空");
        AssertUtils.isEmpty(entity.getPassword(), "密码不能为空");
        AssertUtils.isEmpty(entity.getCodeValue(), "验证码不能为空");
        String cacheCodeValue = (String) RedisUtils.get(RedisConst.CAPTCHA_KEY + entity.getCodeKey());
        AssertUtils.isEmpty(cacheCodeValue, "请先获取验证码");
        AssertUtils.isTrue(!cacheCodeValue.equalsIgnoreCase(entity.getCodeValue()), "验证码错误");
        List<SysUser> userList = userService.list(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserName, entity.getUsername())
                .eq(SysUser::getPassword, SecureUtil.md5(entity.getPassword())));
        AssertUtils.isEmpty(userList, "账号或密码错误");
        AssertUtils.isTrue(userList.size() > 1, "账号异常");
        SysUser sysUser = userList.get(0);
        AssertUtils.isTrue(CompareUtil.compare(sysUser.getIsEnable(), 2L) == 0, "账号已禁用");
        StpUtil.login(sysUser.getId(), SaLoginConfig.setExtra("sysUser", sysUser)
                .setExtra("roleList", userService.listRoleById(sysUser.getId()))
                .setExtra("permissionList", userService.listPermissionById(sysUser.getId())));
        return Result.ok("登录成功", StpUtil.getTokenInfo().getTokenValue());
    }

    @Override
    public Result getInfo() {
        Map<String, Object> map = new HashMap<>(16);
        map.put("user", StpUtil.getExtra("sysUser"));
        map.put("roles", StpUtil.getRoleList());
        map.put("permissions", StpUtil.getPermissionList());
        return Result.ok("获取成功", map);
    }

    @Override
    public Result getMenu() {
        List<SysPermission> permissionList;
        if (StpUtil.hasRole("admin")) {
            permissionList = permissionService.list(new LambdaQueryWrapper<SysPermission>().orderByAsc(SysPermission::getSort));
        } else {
            permissionList = userService.listPermissionById(SaTokenUtils.getUserId());
        }
        permissionList = MenuUtils.getChildPerms(permissionList, 0);
        return Result.ok(MsgConst.QUERY_SUCCESS, MenuUtils.buildMenus(permissionList));
    }

    @Override
    public Result captcha() {
        /*switch (qbootProperties.getLoginCodeMode()) {
            case NUMBER:
                break;
            case LETTER:
                break;
            case BLEND:
                break;
            default:
                break;
        }*/
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(100, 40, 4, 5);
        Map<String, String> map = new HashMap<>(16);
        captcha.createCode();
        String codeKey = IdUtil.simpleUUID();
        RedisUtils.set(RedisConst.CAPTCHA_KEY + codeKey, captcha.getCode(), 300);
        map.put("codeKey", codeKey);
        map.put("image", captcha.getImageBase64());
        return Result.ok("获取成功", map);
    }
}
